package cs.helsinki.fi.rio.matrixmult;

import java.util.ArrayList;


/**
 * 
 * TODO: Change implementation to concurrent one
 * TODO: Prove assumption that concurrent solution would be better scaling
 */
public class MatrixMult {
	
	public static double[][] multiplicateMatrix(double[][] matrix1, double[][] matrix2) {
		ArrayList<double[]> resultMatrix = new ArrayList<double[]>();
		int rows1 = matrix1.length;
		int cols2 = matrix2[0].length;
		for(int i = 0; i < rows1; i++) {
			double[] row = matrix1[i];
			double[] resultRow = new double[cols2];
			for(int j = 0; j < cols2; j++) {
				double[] column = getMatrixColumn(matrix2, j);
				resultRow[j] = calculateMatrixElement(row, column);
			}
			resultMatrix.add(resultRow);
		} 
		
		return convertArrayListToMatrix(resultMatrix);
	}
	
	protected static double[][] convertArrayListToMatrix(ArrayList<double[]> toConvert) {
		
		int rows = toConvert.size();
		int cols = toConvert.get(0).length;
		double[][] resMatrix = new double[rows][cols];
		
		for (int i = 0; i < rows; i++) {
			for (int j= 0; j < cols; j++) {
				resMatrix[i][j] = toConvert.get(i)[j];
			}
		}
		
		return resMatrix;
	}
	
	protected static double[] getMatrixColumn(double[][] tempMatrix, int column) {
		
		int size = tempMatrix[0].length;
		double[] resultCol = new double[size];
		for(int i = 0; i < size; i++) {
			resultCol[i] = tempMatrix[i][column];
		}
		
		return resultCol;
	}
	
	protected static double calculateMatrixElement(double[] row, double[] column) {
//		System.out.print("Row: ");
//		printMatrix(new int[][] {row});
//		System.out.print("Column: ");
//		printMatrix(new int[][] {column});
		int result = 0;
		int len = row.length;
		for(int i = 0; i < len; i++) {
			double x = row[i];
			double y = column[i];
			result += x*y;
		}
		return result;
	}
	
	public static void main(String[] args) {
		double[][] test1 = new double[][] {new double[] {1,2,3}, new double[] {4,5,6}, new double[] {7,8,9}};
		double[][] test2 = new double[][] {new double[] {1,0,2}, new double[] {0,1,2}, new double[] {1,0,0}};
		
		System.out.println(calculateMatrixElement(test1[2], getMatrixColumn(test2, 2)));
		
		double[][] testResult = multiplicateMatrix(test1, test2);
		
		printMatrix(testResult);
		
	}
	
	public static void printMatrix(double[][] toPrint) {
		for (double[] row : toPrint) {
			for(double num : row) {
				System.out.print(num+" ");
			}
			System.out.println();
		}
		System.out.println();
	}

	
}
